package cn.amaake.magicplugin.satoken.Interceptor;

import cn.amaake.magicplugin.satoken.config.MagicApiSaTokenConfig;
import cn.amaake.magicplugin.satoken.config.SaTokenMode;
import cn.amaake.magicplugin.satoken.interfaces.SatokenAbstract;
import cn.amaake.magicplugin.satoken.model.SatokenUser;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
import cn.dev33.satoken.stp.StpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.ssssssss.magicapi.core.exception.MagicLoginException;
import org.ssssssss.magicapi.core.interceptor.RequestInterceptor;
import org.ssssssss.magicapi.core.model.ApiInfo;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse;
import org.ssssssss.script.MagicScriptContext;

public class CustomRequestInterceptor implements RequestInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(CustomRequestInterceptor.class);

    private final MagicApiSaTokenConfig magicApiSaTokenConfig;

    private final SatokenAbstract satokenAbstract;

    private final SaTokenConfig saTokenConfig;


    public CustomRequestInterceptor(MagicApiSaTokenConfig magicApiSaTokenConfig, ApplicationContext applicationContext, SaTokenConfig saTokenConfig){
        this.magicApiSaTokenConfig = magicApiSaTokenConfig;
        satokenAbstract = applicationContext.getBean(SatokenAbstract.class);
        this.saTokenConfig=saTokenConfig;
    }

    /**
     * 接口请求之前
     * @param info	接口信息
     * @param context	脚本变量信息
     */
    @Override
    public Object preHandle(ApiInfo info, MagicScriptContext context, MagicHttpServletRequest request, MagicHttpServletResponse response) throws Exception {

        String id = null;
        if(magicApiSaTokenConfig.getSatokenmode() == SaTokenMode.LOCAL){
            if(info.getOptionValue(Options.ANONYMOUS).equals("true")){
                return null;
            }
            StpUtil.setTokenValue(request.getHeader(saTokenConfig.getTokenName()));
            id = StpUtil.getLoginId().toString();
        }else if(magicApiSaTokenConfig.getSatokenmode() == SaTokenMode.OAUTH2SERVER){
            if(magicApiSaTokenConfig.isCheckClient()){
                String clientToken = request.getHeader("client_token");
                try {
                    ClientTokenModel clientTokenModel = SaOAuth2Util.checkClientToken(clientToken);
                }catch (SaOAuth2Exception e){
                    return new JsonBean<>(403, "clientToken 无效");
                }
            }
            if(info.getOptionValue(Options.ANONYMOUS).equals("true")){
                return null;
            }
            String accessToken = request.getHeader("access_token");
            AccessTokenModel accessTokenModel = null;
            try{
                accessTokenModel = SaOAuth2Util.checkAccessToken(accessToken);
            }catch (SaOAuth2Exception e){
                throw new MagicLoginException("Access-Token无效");
            }
            id = accessTokenModel.loginId.toString();
        }else if(magicApiSaTokenConfig.getSatokenmode() == SaTokenMode.OAUTH2CLIENT){
            String accessToken = request.getHeader("access_token");
            SatokenUser satokenUser = satokenAbstract.getSatokenUserbyid(accessToken);
            id = satokenUser.getId();
        }
        logger.info("{} 请求接口：{}", id, info.getName());
        // 接口选项配置了需要登录

        if ("true".equals(info.getOptionValue(Options.REQUIRE_LOGIN))) {
            if (id == null) {
                return new JsonBean<>(401, "用户未登录");
            }
        }

        String role = info.getOptionValue(Options.ROLE);
        if (StringUtils.isNotBlank(role) ) {
            if(!StpUtil.hasRole(role)){
                return new JsonBean<>(403, "用户权限不足");
            }
        }

        String permission = info.getOptionValue(Options.PERMISSION);
        if (StringUtils.isNotBlank(permission)) {
            if(!StpUtil.hasPermission(permission)){
                return new JsonBean<>(403, "用户权限不足");
            }

        }
        return null;
    }

    /**
     * 接口执行之后
     * @param info	接口信息
     * @param context	变量信息
     * @param returnValue 即将要返回到页面的值
     */
    @Override
    public Object postHandle(ApiInfo info, MagicScriptContext context, Object returnValue, MagicHttpServletRequest request, MagicHttpServletResponse response) throws Exception {
        logger.info("{} 执行完毕，返回结果:{}", info.getName(), returnValue);
        return null;
    }
}